package com.xlh.aop;

import cn.hutool.core.date.DateUtil;
import com.google.common.collect.Lists;
import com.xlh.common.Result;
import com.xlh.common.ResultEnum;
import com.xlh.enums.course.ChapterResourceViewEnum;
import com.xlh.enums.user.EventCodeEnum;
import com.xlh.pojo.system.Operation;
import com.xlh.security.UserInfoHolder;
import com.xlh.service.system.OperationService;
import com.xlh.util.AnnotationResolver;
import org.apache.commons.collections.CollectionUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * 流水记录
 * <p>
 * Created by lx on 2019/1/25.
 */
@Aspect
@Component
public class OperationAspect {

    @Autowired
    private OperationService operationService;

    @Autowired
    private UserInfoHolder userInfoHolder;

    @Around("@annotation(OperationRecording)")
    public Object aroundExecuteApiMethod(ProceedingJoinPoint pJoinPoint) throws Throwable {
        Object o = pJoinPoint.proceed(pJoinPoint.getArgs());
        if (o != null && o instanceof Result
                && Objects.equals(((Result) o).getCode(), ResultEnum.SUCCESS.getCode())) {

            Method method = ((MethodSignature) pJoinPoint.getSignature()).getMethod();
            OperationRecording operation = method.getAnnotation(OperationRecording.class);

            try {
                // 将参数 进行转换
                Long objId = Long.valueOf(AnnotationResolver.resolver(pJoinPoint, operation.objId()));
                Integer type = Integer.valueOf(AnnotationResolver.resolver(pJoinPoint, operation.type()));

                // 插入数据库
                insertDB(objId, ChapterResourceViewEnum.getByCode(type), operation.codeEnum());
            } catch (NumberFormatException e) {

            }
        }
        return o;
    }

    private void insertDB(Long objId, ChapterResourceViewEnum viewEnum, EventCodeEnum eventCodeEnum) {
        List<Operation> operations = Lists.newArrayList();
        operations.add(convertOperation(eventCodeEnum, objId, viewEnum));

        if (eventCodeEnum == EventCodeEnum.CHAPTER_RECORDING) {
            // 查询用户最近学习记录是否是这个章节
            List<Operation> operationList = operationService.listOperation(
                    userInfoHolder.getUserId(), null, eventCodeEnum);
            if (CollectionUtils.isNotEmpty(operationList) && Objects.equals(operationList.get(0).getObjId(), objId)
                    && Objects.equals(DateUtil.formatDate(new Date()) ,
                    DateUtil.formatDate(operationList.get(0).getCreateTime()))) {
                return;
            }
        }

        if (eventCodeEnum == EventCodeEnum.CHAPTER_RECORDING
                && (viewEnum == ChapterResourceViewEnum.EXPERIMENT || viewEnum == ChapterResourceViewEnum.THEORY)) {
            List<Operation> studiedList = operationService.listOperation(
                    userInfoHolder.getUserId(), Lists.newArrayList(objId), EventCodeEnum.CHAPTER_STUDIED);
            if (CollectionUtils.isEmpty(studiedList)) {
                operations.add(convertOperation(EventCodeEnum.CHAPTER_STUDIED, objId, viewEnum));
            }
        }
        operationService.insertBatch(operations);
    }

    private Operation convertOperation(EventCodeEnum codeEnum, Long objId, ChapterResourceViewEnum viewEnum) {
        Operation operation = new com.xlh.pojo.system.Operation();
        operation.setObjId(objId);
        operation.setEventCode(codeEnum.getCode());
        operation.setEventDesc(codeEnum.getMessage());
        operation.setRole(userInfoHolder.getUser().getRole());
        operation.setUserId(userInfoHolder.getUserId());
        operation.setRemark(String.valueOf(viewEnum.getCode()));
        return operation;
    }

}
